// 9.3 顺序容器操作
/**
 * 顺序容器和关联容器的不同之处在于两者组织元素的方式。这些不同之处直接关系到了元素如何存储、访问、添加以及删除。
 *
 * 9.3.3 删除元素
 * 与添加元素的多种方式类似，（非array）容器也有多种删除元素的方式。表9.7列出了这些成员函数。
 * 删除元素的成员函数并不检查其参数。在删除元素之前，程序员必须确保它（们）是存在的。
 */

#include <vector>
#include <list>
#include <deque>
#include <forward_list>
#include <string>
#include <array>
using std::swap;
using std::vector, std::list, std::deque, std::forward_list, std::string, std::array;
#include "../Chapter07/Sales_data.h"
#include <iostream>
using std::cin, std::cout, std::endl;

int main()
{
    // pop_front和pop_back成员函数
    /**
     * pop_front和pop_back成员函数分别删除首元素和尾元素。与vector和string不支持push_front一样，这些类型也不支持pop_front。
     * 类似的，forward_list不支持pop_back。与元素访问成员函数类似，不能对一个空容器执行弹出操作。
     */
    list<int> ilist1;
    while (!ilist1.empty())
    {
        ilist1.pop_front(); // 删除首元素
        ilist1.pop_back();  // 删除尾元素
    }

    // 从容器内部删除一个元素
    /**
     * 成员函数erase从容器中指定位置删除元素。我们可以删除由一个迭代器指定的单个元素，也可以删除由一对迭代器指定的范围内的所有元素。
     * 两种形式的erase都返回指向删除的（最后一个）元素之后位置的迭代器。即，若j是i之后的元素，那么erase（i）将返回指向j的迭代器。
     */
    list<int> lst = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    auto it = lst.begin();
    while (it != lst.end())
    {
        if (*it % 2)            // 若元素为奇数
            it = lst.erase(it); // 删除此元素，并返回指向删除元素之后置位的迭代器
        else
            ++it;
    }

    // 删除多个元素
    /**
     * 接受一对迭代器的erase版本允许我们删除一个范围内的元素。
     */
    auto elem1 = lst.erase(lst.begin(), lst.end()); // 返回指向最后一个被删元素之后位置的迭代器

    return 0;
}